package com.yudean.esb.domain.erp;

import com.yudean.esb.domain.esb.EsbRecvServiceTempData;
import jodd.vtor.Check;
import jodd.vtor.ValidationContext;
import jodd.vtor.Vtor;
import jodd.vtor.constraint.NotNullConstraint;
import org.dozer.DozerBeanMapper;
import org.dozer.loader.api.BeanMappingBuilder;
import org.dozer.loader.api.TypeMappingOptions;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static org.dozer.loader.api.FieldsMappingOptions.hintA;
import static org.dozer.loader.api.FieldsMappingOptions.hintB;

public class ErpFwsContract implements Serializable {
    /**
     *
     */
    private static final long serialVersionUID = -3949923094449784328L;

    private Long controlId;

    private String compCode;

    private String contractCode;

    private String contractName;

    private String contractType;

    private String vendorCode;

    private String vendorName;

    private String contractDesc;

    private BigDecimal originalAmount;

    private String paymentTerm;

    private BigDecimal contractAmount;

    private Date creationDate;
    private String creationDateStr;

    private Integer createdBy;

    private Date lastUpdateDate;
    private String lastUpdateDateStr;


    private Integer lastUpdatedBy;

    private String attribute1;

    private String attribute2;

    private String attribute3;

    private String attribute4;

    private String attribute5;

    private String attribute6;

    private String attribute7;

    private String attribute8;

    private String attribute9;

    private String attribute10;

    //以下两个属性只需要保存到交换平台 临时库，不需要同步到ERP
    private String vendorAmount;
    private String initPaid;
    private List<ErpContractVendor> vendorList;


    public long getControlId() {
        return controlId;
    }

    public void setControlId(long controlId) {
        this.controlId = controlId;
    }

    public String getCompCode() {
        return compCode;
    }

    public void setCompCode(String compCode) {
        this.compCode = compCode;
    }

    public String getContractCode() {
        return contractCode;
    }

    public void setContractCode(String contractCode) {
        this.contractCode = contractCode;
    }

    public String getContractName() {
        return contractName;
    }

    public void setContractName(String contractName) {
        this.contractName = contractName;
    }

    public String getContractType() {
        return contractType;
    }

    public void setContractType(String contractType) {
        this.contractType = contractType;
    }

    public String getVendorCode() {
        return vendorCode;
    }

    public void setVendorCode(String vendorCode) {
        this.vendorCode = vendorCode;
    }

    public String getVendorName() {
        return vendorName;
    }

    public void setVendorName(String vendorName) {
        this.vendorName = vendorName;
    }

    public String getContractDesc() {
        return contractDesc;
    }

    public void setContractDesc(String contractDesc) {
        this.contractDesc = contractDesc;
    }

    public BigDecimal getOriginalAmount() {
        return originalAmount;
    }

    public void setOriginalAmount(BigDecimal originalAmount) {
        this.originalAmount = originalAmount;
    }

    public String getPaymentTerm() {
        return paymentTerm;
    }

    public void setPaymentTerm(String paymentTerm) {
        this.paymentTerm = paymentTerm;
    }

    public BigDecimal getContractAmount() {
        return contractAmount;
    }

    public void setContractAmount(BigDecimal contractAmount) {
        this.contractAmount = contractAmount;
    }

    public Date getCreationDate() {
        return creationDate;
    }

    public void setCreationDate(Date creationDate) {
        this.creationDate = creationDate;
    }

    public String getCreationDateStr() {
        return creationDateStr;
    }

    public void setCreationDateStr(String creationDateStr) {
        this.creationDateStr = creationDateStr;
        this.creationDate = ErpControl.longDateParser(creationDateStr);
    }

    public Integer getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(Integer createdBy) {
        this.createdBy = createdBy;
    }

    public Date getLastUpdateDate() {
        return lastUpdateDate;
    }

    public void setLastUpdateDate(Date lastUpdateDate) {
        this.lastUpdateDate = lastUpdateDate;
    }

    public String getLastUpdateDateStr() {
        return lastUpdateDateStr;
    }

    public void setLastUpdateDateStr(String lastUpdateDateStr) {
        this.lastUpdateDateStr = lastUpdateDateStr;
        this.lastUpdateDate = ErpControl.longDateParser(lastUpdateDateStr);
    }

    public Integer getLastUpdatedBy() {
        return lastUpdatedBy;
    }

    public void setLastUpdatedBy(Integer lastUpdatedBy) {
        this.lastUpdatedBy = lastUpdatedBy;
    }

    public String getAttribute1() {
        return attribute1;
    }

    public void setAttribute1(String attribute1) {
        this.attribute1 = attribute1;
    }

    public String getAttribute2() {
        return attribute2;
    }

    public void setAttribute2(String attribute2) {
        this.attribute2 = attribute2;
    }

    public String getAttribute3() {
        return attribute3;
    }

    public void setAttribute3(String attribute3) {
        this.attribute3 = attribute3;
    }

    public String getAttribute4() {
        return attribute4;
    }

    public void setAttribute4(String attribute4) {
        this.attribute4 = attribute4;
    }

    public String getAttribute5() {
        return attribute5;
    }

    public void setAttribute5(String attribute5) {
        this.attribute5 = attribute5;
    }

    public String getAttribute6() {
        return attribute6;
    }

    public void setAttribute6(String attribute6) {
        this.attribute6 = attribute6;
    }

    public String getAttribute7() {
        return attribute7;
    }

    public void setAttribute7(String attribute7) {
        this.attribute7 = attribute7;
    }

    public String getAttribute8() {
        return attribute8;
    }

    public void setAttribute8(String attribute8) {
        this.attribute8 = attribute8;
    }

    public String getAttribute9() {
        return attribute9;
    }

    public void setAttribute9(String attribute9) {
        this.attribute9 = attribute9;
    }

    public String getAttribute10() {
        return attribute10;
    }

    public void setAttribute10(String attribute10) {
        this.attribute10 = attribute10;
    }

    public String getVendorAmount() {
        return vendorAmount;
    }

    public void setVendorAmount(String vendorAmount) {
        this.vendorAmount = vendorAmount;
    }

    public String getInitPaid() {
        return initPaid;
    }

    public void setInitPaid(String initPaid) {
        this.initPaid = initPaid;
    }

    public List<ErpContractVendor> getContractVendors() {
        if ("".equals(this.vendorCode)) {
            return null;
        }
        this.vendorList = new ArrayList<ErpContractVendor>();

        String[] vendorCodes = this.getVendorCode().split(";");
        String[] vendorNames = this.getVendorName().split(";");
        String[] vendorAmounts = this.getVendorAmount().split(";");
        String[] vendorInitAmount = this.initPaid.split(";");
        for (int idx = 0; idx < vendorCodes.length; ++idx) {
            ErpContractVendor vendor = new ErpContractVendor();
            vendor.setVendorCode(vendorCodes[idx]);
            vendor.setVendorName(vendorNames[idx]);

            vendor.setAmountByVendor(new BigDecimal(vendorAmounts[idx].trim()));
            vendor.setInitPaid(new BigDecimal(vendorInitAmount[idx].trim()));

            vendor.setContractCode(this.getContractCode());
            vendor.setControlId(this.getControlId());
            vendor.setLastUpdateDate(this.getLastUpdateDate());
            vendor.setCreationDate(this.getCreationDate());
            this.vendorList.add(vendor);
        }
        return this.vendorList;
    }

    /**
     * 判断是否有不满足的约束的地方
     *
     * @return TRUE 有不满足要求的字段信息，FALSE 数据符合规范
     */
    public boolean hasViolations() {
        //先验证供应商数据
        if ("".equals(this.vendorCode)) {
            return true;
        }
        //数据域字段验证
        if (validationContext == null)
            validationContext = getValidationContext();
        Vtor vtor = new Vtor();
        vtor.validate(validationContext, this);
        //如果字段不合法，直接返回
        if (vtor.hasViolations())
            return vtor.hasViolations();

        //现在需要匹配个数是否一致，不一致就返回
        String[] vendorCodes = this.getVendorCode().split(";");
        String[] vendorNames = this.getVendorName().split(";");
        String[] vendorAmounts = this.getVendorAmount().split(";");
        String[] vendorInitAmount = this.initPaid.split(";");
        //供应商数据无法对应
        if (vendorCodes.length != vendorAmounts.length || vendorCodes.length != vendorInitAmount.length)
            return true;

        return false;
    }

    /**
     * 用来构造验证字段的上下文
     *
     * @return 验证规范
     */
    private static ValidationContext getValidationContext() {
        ValidationContext vctx = new ValidationContext();
        vctx.add(new Check("controlId", new NotNullConstraint()));
        vctx.add(new Check("compCode", new NotNullConstraint()));
        vctx.add(new Check("contractCode", new NotNullConstraint()));
        vctx.add(new Check("vendorCode", new NotNullConstraint()));
        vctx.add(new Check("contractName", new NotNullConstraint()));
        vctx.add(new Check("vendorAmount", new NotNullConstraint()));
        vctx.add(new Check("initPaid", new NotNullConstraint()));
        return vctx;
    }

    // 验证的条件
    private static ValidationContext validationContext = null;
    private static DozerBeanMapper mapper;
    // 临时数据转存关系
    private static BeanMappingBuilder contractMapping = new BeanMappingBuilder() {
        @Override
        protected void configure() {
            //对于日期的转换
            String dateFormat = "yyyy-MM-dd HH:mm:ss";
            mapping(Map.class, ErpFwsContract.class,
                    TypeMappingOptions.dateFormat(dateFormat))
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE1"),
                            "controlId",
                            hintA(String.class),
                            hintB(Long.class))
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE2"), "compCode")
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE3"), "contractCode")
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE4"), "contractName")
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE5"), "vendorCode")
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE6"), "vendorName")
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE7"), "contractDesc")
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE8"),
                            "originalAmount",
                            hintA(String.class),
                            hintB(BigDecimal.class))
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE9"), "paymentTerm")
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE10"),
                            "contractAmount",
                            hintA(String.class),
                            hintB(BigDecimal.class))
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE11"), "creationDate",
                            hintA(String.class),
                            hintB(Date.class))
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE25"),
                            "createdBy",
                            hintA(String.class),
                            hintB(Integer.class))
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE12"), "lastUpdateDate",
                            hintA(String.class),
                            hintB(Date.class))
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE26"),
                            "lastUpdatedBy",
                            hintA(String.class),
                            hintB(Integer.class))
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE13"), "attribute1")
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE14"), "attribute2")
                    .fields(ErpControl.getMapperDefine("attribute15"), "attribute3")
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE16"), "attribute4")
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE17"), "attribute5")
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE18"), "attribute6")
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE19"), "attribute7")
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE20"), "attribute8")
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE21"), "attribute9")
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE22"), "attribute10")
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE23"), "vendorAmount")
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE24"), "initPaid")
                    .fields(ErpControl.getMapperDefine("ATTRIBUTE31"), "contractType")
                    .exclude("contractVendors")
            ;
        }
    };


    static {
        mapper = new DozerBeanMapper();
        mapper.addMapping(contractMapping);
    }

    /**
     * 转换成临时数据存储对象
     *
     * @return 临时对象
     */
    public EsbRecvServiceTempData convert2TmpData() {
        Map<String, Object> data = mapper.map(this, Map.class);
        data.put("ATTRIBUTE99", "FWS-TMP-DATA");

        EsbRecvServiceTempData tmpData = new EsbRecvServiceTempData();
        tmpData.setIsProcessed("1");
        tmpData.setID("FWS-ERP-CONTRACT");
        tmpData.setPackageID(this.getControlId() + "");
        tmpData.setOperation("T");
        tmpData.setTransactionID(this.getContractCode());

        ArrayList<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        list.add(data);
        tmpData.setData(list);
        return tmpData;
    }

    /**
     * 将临时表的信息转存为合同数据
     *
     * @param tmpData 临时表
     * @return 合同数据集合
     */
    public static ErpFwsContract mapToThis(Map<String, Object> tmpData) {
        if (tmpData == null) {
            return null;
        }
        return mapper.map(tmpData, ErpFwsContract.class);
    }

    @Override
    public String toString() {
        return "ErpFwsContract{" +
                "controlId=" + controlId +
                ", compCode='" + compCode + '\'' +
                ", contractCode='" + contractCode + '\'' +
                ", contractName='" + contractName + '\'' +
                ", contractType='" + contractType + '\'' +
                ", vendorCode='" + vendorCode + '\'' +
                ", vendorName='" + vendorName + '\'' +
                ", contractDesc='" + contractDesc + '\'' +
                ", originalAmount=" + originalAmount +
                ", paymentTerm='" + paymentTerm + '\'' +
                ", contractAmount=" + contractAmount +
                ", creationDate=" + creationDate +
                ", creationDateStr='" + creationDateStr + '\'' +
                ", createdBy=" + createdBy +
                ", lastUpdateDate=" + lastUpdateDate +
                ", lastUpdateDateStr='" + lastUpdateDateStr + '\'' +
                ", lastUpdatedBy=" + lastUpdatedBy +
                ", attribute1='" + attribute1 + '\'' +
                ", attribute2='" + attribute2 + '\'' +
                ", attribute3='" + attribute3 + '\'' +
                ", attribute4='" + attribute4 + '\'' +
                ", attribute5='" + attribute5 + '\'' +
                ", attribute6='" + attribute6 + '\'' +
                ", attribute7='" + attribute7 + '\'' +
                ", attribute8='" + attribute8 + '\'' +
                ", attribute9='" + attribute9 + '\'' +
                ", attribute10='" + attribute10 + '\'' +
                ", vendorAmount='" + vendorAmount + '\'' +
                ", initPaid='" + initPaid + '\'' +
                '}';
    }
}
